/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package controladorfuzzy;

;

import java.util.ArrayList;

/**
 *FALTA TERMINAR.
 * @author Administrador
 */
public class Defuzzificacao {

    ArrayList<Expressao> expressoes;
    ConjuntoFuzzy conjuntoResultado;
    double velocidade;

    public Defuzzificacao(ArrayList<Expressao> expressoesInformadas, ConjuntoFuzzy conjuntoResultado) {
        this.expressoes = expressoesInformadas;
        this.conjuntoResultado = conjuntoResultado;
    }

    public double deffuzificar() {
        double area1 = 0;
        double area2 = 0;
        double area3 = 0;
        double centroide1 = 0;
        double centroide2 = 0;
        double centroide3 = 0;
        agregar();

        //Para atribuir os valores a primeira área
        if (conjuntoResultado.getPrimeiroValor().equals("baixa")) {
            centroide1 = calcularCentroide(0, conjuntoResultado.pontos.get(1));
//            System.out.println("Base Maior: " + conjuntoResultado.pontos.get(1));
            area1 = calcularAreaTrapezio(conjuntoResultado.pontos.get(1), "baixa", conjuntoResultado.getPrimeiraPertinencia());
        } else if (conjuntoResultado.getPrimeiroValor().equals("media")) {
            centroide1 = calcularCentroide(conjuntoResultado.pontos.get(0), conjuntoResultado.pontos.get(3));
            double baseMaior = conjuntoResultado.pontos.get(3) - conjuntoResultado.pontos.get(0);
            area1 = calcularAreaTrapezio(baseMaior, "media", conjuntoResultado.getPrimeiraPertinencia());
        } else if (conjuntoResultado.getPrimeiroValor().equals("alta")) {
            centroide1 = calcularCentroide(conjuntoResultado.pontos.get(2), 30);
            double baseMaior = 30 - conjuntoResultado.pontos.get(2);
            area1 = calcularAreaTrapezio(baseMaior, "alta", conjuntoResultado.getPrimeiraPertinencia());
        }

        //Para atribuir os segundos valores
        if (conjuntoResultado.getSegundaPertinencia() != 0) {
            if (conjuntoResultado.getSegundoValor().equals("baixa")) {
                centroide2 = calcularCentroide(0, conjuntoResultado.pontos.get(1));
                area2 = calcularAreaTrapezio(conjuntoResultado.pontos.get(1), "baixa", conjuntoResultado.getSegundaPertinencia());
            } else if (conjuntoResultado.getSegundoValor().equals("media")) {
                centroide2 = calcularCentroide(conjuntoResultado.pontos.get(0), conjuntoResultado.pontos.get(3));
                double baseMaior = conjuntoResultado.pontos.get(3) - conjuntoResultado.pontos.get(0);
                area2 = calcularAreaTrapezio(baseMaior, "media", conjuntoResultado.getSegundaPertinencia());
            } else if (conjuntoResultado.getSegundoValor().equals("alta")) {
                centroide2 = calcularCentroide(conjuntoResultado.pontos.get(2), 30);
                double baseMaior = 30 - conjuntoResultado.pontos.get(2);
                area2 = calcularAreaTrapezio(baseMaior, "alta", conjuntoResultado.getSegundaPertinencia());
            }
        }
//        System.out.println("Dados da Defuzzificação");
//        System.out.println("Área 1: " + area1);
//        System.out.println("Área 1: " + area2);
//        System.out.println("Centroide 1: " + centroide1);
//        System.out.println("Centroide 2: " + centroide2);

        velocidade = (centroide1 * area1 + centroide2 * area2 + centroide3 * area3) / (area1 + area2 + area3);
        if (velocidade < 5.0) {
            return 0;
        } else {
            return velocidade;
        }
    }

    public double calcularCentroide(double limiteMinimo, double limiteMaximo) {
        double resultado;
        resultado = (limiteMinimo + limiteMaximo) / 2;
        return resultado;
    }

    public double calcularAreaTrapezio(double baseMaior, String valor, double altura) {
        double resultado = 0;
        double baseMenor = calcularBaseMenor(altura, valor);
        resultado = ((baseMaior + baseMenor) * altura) / 2;
        return resultado;
    }

    public double calcularBaseMenor(double y, String valor) {
        double resultado = 0;
        double[] pontosX;
        pontosX = conjuntoResultado.obterX(y, valor);
        resultado = pontosX[1] - pontosX[0];
        return resultado;
    }

    public void agregar() {
        String primeiroResultadoAgregado, segundoResultadoAgregado;
        double primeiraMaiorPertinencia = 0;
        double segundaMaiorPertinencia = 0;

        primeiroResultadoAgregado = expressoes.get(0).getConsequenteValor();
        conjuntoResultado.setPrimeiroValor(primeiroResultadoAgregado);

        for (int i = 0; i < expressoes.size(); i++) {
            if (expressoes.get(i).getConsequenteValor().equals(primeiroResultadoAgregado)) {
                if (expressoes.get(i).getConsequentePertinencia() > primeiraMaiorPertinencia) {
                    primeiraMaiorPertinencia = expressoes.get(i).getConsequentePertinencia();
                }
            } else if (!expressoes.get(i).getConsequenteValor().equals("x") && !expressoes.get(i).getConsequenteValor().equals(primeiroResultadoAgregado)) {
                segundoResultadoAgregado = expressoes.get(i).getConsequenteValor();
                conjuntoResultado.setSegundoValor(segundoResultadoAgregado);

                if (expressoes.get(i).getConsequentePertinencia() > segundaMaiorPertinencia) {
                    segundaMaiorPertinencia = expressoes.get(i).getConsequentePertinencia();
                }
            }
        }
        conjuntoResultado.setPrimeiraPertinencia(primeiraMaiorPertinencia);
        conjuntoResultado.setSegundaPertinencia(segundaMaiorPertinencia);
        imprimirAgregação();
    }

    public void imprimirAgregação() {
        System.out.println("");
        System.out.println("---Imprimindo resultado da agregação---");
        System.out.println(conjuntoResultado.getPrimeiraPertinencia() + " " + conjuntoResultado.getPrimeiroValor());
        System.out.println(conjuntoResultado.getSegundaPertinencia() + " " + conjuntoResultado.getSegundoValor());

    }
}
